package com.zzzyh.forumsystemclient.services.impl;

import com.zzzyh.forumsystemclient.services.ISignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SignServiceImpl implements ISignService {
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 检查用户今天是否已经签到
     *
     * @param userId 用户ID
     * @return true 如果已签到，false 否则
     */
    @Override
    public boolean hasSignedToday(Integer userId) {
        String key = "sign:" + userId;
        String today = LocalDate.now().format(DateTimeFormatter.ISO_DATE);
        return Boolean.TRUE.equals(redisTemplate.opsForHash().hasKey(key, today));
    }

    /**
     * 执行签到操作
     *
     * @param userId 用户ID
     * @return true 如果成功签到，false 如果已经签过
     */
    @Override
    public boolean sign(Integer userId) {
        if (hasSignedToday(userId)) {
            return false; // 已经签到
        }
        String key = "sign:" + userId;
        String today = LocalDate.now().format(DateTimeFormatter.ISO_DATE);
        redisTemplate.opsForHash().put(key, today, 1); // 记录签到
        return true;
    }

    /**
     * 获取用户某天的签到状态
     *
     * @param userId 用户ID
     * @param date   查询的日期（格式：yyyy-MM-dd）
     * @return true 如果指定日期已签到，false 否则
     */
    @Override
    public boolean getSignStatus(Integer userId, String date) {
        String key = "sign:" + userId;
        return Boolean.TRUE.equals(redisTemplate.opsForHash().hasKey(key, date));
    }

    /**
     * 获取用户最大连续签到天数
     *
     * @param userId 用户ID
     * @return 最大连续签到天数
     */
    @Override
    public int getMaxConsecutiveDays(Integer userId) {
        String key = "sign:" + userId;
        Map<Object, Object> signRecords = redisTemplate.opsForHash().entries(key);

        if (signRecords.isEmpty()) {
            return 0; // 没有签到记录
        }

        // 提取所有签到日期并排序
        List<LocalDate> dates = signRecords.keySet().stream()
                .map(dateStr -> LocalDate.parse((String) dateStr))
                .sorted()
                .collect(Collectors.toList());

        int maxStreak = 1;
        int currentStreak = 1;

        for (int i = 1; i < dates.size(); i++) {
            LocalDate prev = dates.get(i - 1);
            LocalDate curr = dates.get(i);

            if (curr.isEqual(prev.plusDays(1))) {
                currentStreak++;
                maxStreak = Math.max(maxStreak, currentStreak);
            } else {
                currentStreak = 1; // 中断连续
            }
        }

        return maxStreak;
    }


    // 获取总签到次数
    @Order
    public long getTotalSignedDays(Integer userId) {
        String key = "sign:" + userId;
        return redisTemplate.opsForHash().size(key);
    }

    // 获取当前连续签到天数
    @Order
    public int getCurrentConsecutiveDays(Integer userId) {
        String key = "sign:" + userId;
        Map<Object, Object> signRecords = redisTemplate.opsForHash().entries(key);

        if (signRecords.isEmpty()) {
            return 0; // 没有签到记录
        }

        // 提取并排序所有签到日期
        List<LocalDate> dates = signRecords.keySet().stream()
                .map(dateStr -> LocalDate.parse((String) dateStr))
                .sorted()
                .collect(Collectors.toList());

        int currentStreak = 1;
        Collections.reverse(dates); // 倒序排列，从最近的日期开始判断

        for (int i = 1; i < dates.size(); i++) {
            LocalDate prev = dates.get(i - 1);
            LocalDate curr = dates.get(i);

            if (curr.isEqual(prev.minusDays(1))) {
                currentStreak++;
            } else {
                break; // 不连续则停止
            }
        }

        return currentStreak;
    }
}
